import axios, {Method} from 'axios';
import {notification} from 'antd';
import { get, isEmpty } from 'lodash';

export interface Requests {
  [key: string]: {
    url: string;
    method: string;
  };
}
interface requestType {
  [key: string]: any;
}
interface Query {
  [key: string] : string | number | boolean
}
interface Options {
    params?: requestType,
    body?: requestType | FormData,
    headers?: requestType,
    query?: Query
}
interface responseType {
  code: number;
  data: any,
  message?: string;
}
export interface Reponse {
  [key: string]: (options?: Options) => Promise<any>;
}
interface AxiosResponse {
  'code': number,
  'data': any,
  'message': string
}
// 添加请求拦截器
axios.interceptors.request.use(
  function (config) {
    return config;
  },
  function (error) {
    return Promise.reject(error);
  }
);
// let token = false;
// 添加响应拦截器
axios.interceptors.response.use(
  function (response: any) {
    // 拦截未登录状态
    if(response.data.code === 5151) {
      window.location.href= `http://82.157.8.10:9119/#/?redirectUrl=${location.href}`;

    }
    if(response.data.code !== 2000) {
      let content = JSON.stringify({
        code: response.data.code,
        message:  response.data.message
      }, null, 2)
      notification.error({
        message: '请求错误',
        description: content
      });
      throw new Error(content);
    }
    return response.data.data;
  },
  function (error) {
    return Promise.reject(error);
  }
);
// 公共配置
axios.defaults.timeout = 10 * 1000;

// axios.defaults.headers = {
//   // 鉴权
//   // 'satoken': window.sessionStorage.getItem('satoken') || '',
//   // 'accessToken': window.localStorage.getItem('accessToken') || ''
// }
// 定义三种参数类型（query、params、body）
// query    https://www.xxx.com/{id} => https://www.xxx.com/1234
// params   https://www.xxx.com?key=value
// body     请求体的body里面发送参数

const request = (requests: Requests): Reponse => {
  let apis: Reponse = {};
  let apiKeys = Object.keys(requests);
  apiKeys.forEach((api: string) => {
    let method = get(requests[api], 'method', 'get').toLowerCase() as Method;
    let oldUrl = get(requests[api], 'url', '');
    if (['get', 'delete'].includes(method)) {
      apis[api] = (options = {}):Promise<responseType>  => {
        const {params, body, headers, query = {}} = options as Options;
        let url = oldUrl;
        if(!isEmpty(query)) {
          url = getUrl(oldUrl, query)
        }
        return new Promise((resolve, reject) => {
          axios.request({
            url,
            method,
            headers: headers || {},
            params: params,
          })
            .then((res: any) => {
              resolve(res);
            })
            .catch((err: any) => reject(err));
        });
      };
    } else if (['put', 'post'].includes(method)) {
      apis[api] = (options = {}): Promise<responseType> => {
        const {params, body, headers, query = {}} = options as Options;
        let url = oldUrl;
        if(!isEmpty(query)) {
          url = getUrl(oldUrl, query)
        }
        return new Promise((resolve, reject) => {
          axios.request({
            url,
            data: body,
            method,
            headers: headers,
            params: params,
          })
            .then((res: any) => resolve(res))
            .catch((err: any) => reject(err));
        });
      };
    } else {
      throw new Error('The request method is not within the specified method');
    }
  });
  return apis;
};

const getUrl = (
  url: string,
  query: Query
): string => {
  let urlReg = /\{(\w+)\}/;
  function render(
    url: string,
    query: Query
  ): string {
    if(urlReg.test(url)) {
      const name = (urlReg.exec(url) as RegExpExecArray)[1]
      url = url.replace(urlReg, query[name] as any);
      return render(url, query);
    }
    return url;
  }
  url = render(url, query);
  return url;
}

export default request;


